/**
 * @class $$.sql.reader.Querist
 */
/*
bar = {
	select : [news.id, news.title, newsclass.title, newsclass.id, user.id, user.title]
}
*/
$$.sql.reader.Querist = {
	constructor: function(){
		var data = this.data;
		if(!data) {
			data = this.data = {};
		}
		
		data.mainTable			= '';
		
		data.top				= {};
		data.top.value			= 0;
		data.top.sql			= '';
		
		data.field				= {};
		data.field.value		= [];
		data.field.sql			= '';
		
		data.subQuery			= {};
		data.subQuery.value		= [];
		data.subQuery.sql		= '';
		
		data.join				= {};
		data.join.value			= [];
		data.join.sql			= '';	
		
		data.filter				= {};
		data.filter.value		= [];
		data.filter.sql			= '';	
		
		data.orderBy			= {};
		data.orderBy.value		= [];
		data.orderBy.sql		= '';	
					
		data.noConflict			= {};
		data.noConflict.sql		= '';
	}

	// for First
	,setTop : function(num){
		this.data.top.value = num
		this.data.top.sql   = "TOP " + num;
		return this;
	}
	
	,setField : function(field){
		this.data.field.value.push(field);
		this.data.field.sql += ' '+ field + ' ';
		return this;
	}
	
	// for fields
	,setSubQuery : function(queristInstance, token){
		this.data.subQuery.value.push(queristInstance);
		this.data.subQuery.sql += ',(' + queristInstance.read() + ') AS ' + token;
		return this;
	}
	
	,setFrom : function(mainTable){
		this.data.mainTable = mainTable;
		return this; 
	}
	
	/**
	 * for tables
	 * 生成下面的语句：
	 * USER] INNER JOIN (news INNER JOIN newsClass ON news.ClassID = newsClass.ID) ON USER.ID = news.SubmitterID;
	 * 有两个关系：
	 * student(s#,sname,d#),即学生这个关系有三个属性：学号，姓名，所在系别
	 * dep(d#,dname)，即院系有两个属性：系号、系名则s＃、d＃是主键，也是各自所在关系的唯一候选键，d＃是student的外键。
	 */
	,setJoin : (function(){
		var  tpl = "({1} INNER JOIN {0} ON {3}.{4} = {1}.{2})";
		
		/**
		 * @param  {String}	mainTable
		 * @param  {Array}	tables
		 * @return {String}
		 */
		function makeJoin(mainTable, tables){
			var  
			 join
			,table 
			,inner		// 内面一层的join
			,out	= []; // Is this useful? @todo
	
			for(var i = 0, j = tables.length; i < j; i++){
				
				 table = tables[i]
				,inner = (i == 0) ? mainTable : out[i - 1]
				,join  = tpl.format(
					 inner
					,table.tableName
					,table.primaryKey
					,mainTable
					,table.foreignKey
				);
				
				out.push(join);
				
				// SELECT fields, noConflict
				if(table.noConflict){
					var noConflict = new String(' ');
					for(var q = 0, p = table.noConflict.length; q < p; q++){
						noConflict += ',' + table.noConflict[q] + ' ';
					}
					this.data.noConflict.sql = this.data.noConflict.sql + noConflict;
				}
			}
			return join;
		}
		return 	function(mainTable, tables){
			var thisJoin = this.data.join;
			
			// 保存value，就是保存參數
			thisJoin.value.push([ mainTable, tables]);
			// 不用join，沒有tables
			if(!tables){
				thisJoin.sql = mainTable;
				return thisJoin.sql;
			}
			
			// 如果有sql值存在，表示這是第二次調用join()，則mainTable為fn.sql
			if(thisJoin.sql && thisJoin.sql != ''){
				mainTable = thisJoin.sql;
			}
			
			thisJoin.sql = makeJoin.call(this, mainTable, tables); // 每次join操作都会破坏旧字符串
			return thisJoin.sql;
		}
	})()
	
	,addJoin : function(join){
		var tmpJoin = this.data.tmpJoin;
		if(!tmpJoin){
			tmpJoin	= this.data.tmpJoin = [];
		}
		tmpJoin.push(join);
		return this;
	}
	
	// for where
	,setFilter : function(filter){
		this.data.filter.value.push(filter);
		this.data.filter.sql += ' '+ filter + ' ';
		return this;
	}

	// for order
	,orderBy : function(){
		return emptyStr;
		return this;
	}

	// for page
	,limit : function(){
		return emptyStr;
		return this;
	}	
	
	,read : function(){
		var 
		 dummyStr	= ''
		,data		= this.data 
		,top 		// first
		,fields		// 字段
		,tables		// 关联表
		,filter 	// 查询条件
		,order;		// 排序

		 top	= data.top						.sql 	|| dummyStr
		,fields = (data.field.sql +  data.noConflict.sql)
		,fields = (
			 (data.field						.sql	|| dummyStr) 
			+(data.noConflict					.sql	|| dummyStr)
			+(data.subQuery						.sql	|| dummyStr)
		)												|| ' * '
		,tables = this.setJoin(data.mainTable, data.tmpJoin)
		,filter = data.filter.sql
		,filter = filter ? ' WHERE ' + filter 		 	 : dummyStr
		,order  = data.orderBy					.sql	|| dummyStr;
		
		fields += data.noConflict.sql; // a bug?
		
		return "SELECT " + top + fields + ' FROM ' + tables + filter + order;
	}
};